package service

import (
	"common/biz"
	"common/logs"
	"context"
	"core/dao"
	"core/models/entity"
	"core/repo"
	"fmt"
	"framework/msError"
	"github.com/smartwalle/alipay/v3"
	"hall/pay/service"
	"net/url"
	"strconv"
	"time"
	"user/pb"
)

type AlipayService struct {
	userDao  *dao.UserDao
	goodsDao *dao.GoodsDao
	pb.UnimplementedAlipayCallbackPayServiceServer
}

func (s *AlipayService) Register(ctx context.Context, req *pb.AlipayCallbackPayParams) (*pb.AlipayCallbackPayResponse, error) {
	response := req.CheckValue
	logs.Info("[aliPay] 数据:%v", response)
	//response = "app_id=9021000137690452&auth_app_id=9021000137690452&buyer_id=2088722037046773&buyer_logon_id=mfqdoj8521%40sandbox.com&buyer_pay_amount=1.00&charset=utf-8&fund_bill_list=%5B%7B%22amount%22%3A%221.00%22%2C%22fundChannel%22%3A%22ALIPAYACCOUNT%22%7D%5D&gmt_create=2024-06-14+18%3A03%3A27&gmt_payment=2024-06-14+18%3A03%3A27&invoice_amount=1.00&notify_id=2024061401222180328146770502954619&notify_time=2024-06-14+18%3A03%3A29&notify_type=trade_status_sync&out_trade_no=GOODS2024061418031749G8phsWD&passback_params=method%3Dweb%26module%3Dgoods_order%26uid%3D7&point_amount=0.00&receipt_amount=1.00&seller_email=mcwcxq5537%40sandbox.com&seller_id=2088721037046761&sign=hW2eajC%2BDGus54BYOQxbxRV5fnGUmJayFSZRtohgoTtkY9ZY6%2BIAcgTkV2lESukR1CBMkgdJwyP9UYmx8fgnH6vr9hCpJ0fczy2q%2FWVfh37OJRI8%2FHgqnSA0Lkz%2FwvkwRBZewIz06brrJY%2BnKu65bomBhieNivuTjFHXUFPZXMueyxysdAE5pt1nfIzm7s%2B1EDcD4fE1Ed6Zy3rGVxFLUdsmsCgG%2BgrGlEXuxLqKdR%2BVeTWxqWTuuH%2FFnQBGHROyvcozDr14q1QGfVqBHgPhzDthN2bknpsIfvo%2B1zf3ps4d304YBf8XeknNiqI2XwgTr6U%2FyKBcOE7md3XZw6rOBw%3D%3D&sign_type=RSA2&subject=%E6%B5%8B%E8%AF%95-%E5%95%86%E5%93%81&total_amount=1.00&trade_no=2024061422001446770502906685&trade_status=TRADE_SUCCESS&version=1.0"
	m, _ := url.ParseQuery(response)
	client, err := service.AliPay("web")
	if err != nil {
		logs.Error("AlipayCallbackPay Register err=获取证书失败,res=%v,fErr=%v", response, err)
		return &pb.AlipayCallbackPayResponse{}, msError.GrpcError(biz.RequestDataError)
	}
	notification, err := client.DecodeNotification(m)
	if err != nil {
		logs.Error("AlipayCallbackPay Register err=解密失败,res=%v,fErr=%v", response, err)
		return &pb.AlipayCallbackPayResponse{}, msError.GrpcError(biz.RequestDataError)
	}
	//passbackParams := make(map[string]any)
	//_ = json.Unmarshal([]byte(notification.PassbackParams), &passbackParams)
	passbackParams, _ := url.ParseQuery(notification.PassbackParams)
	uidInt, _ := strconv.Atoi(passbackParams.Get("uid"))
	uid := uint(uidInt)
	if notification.TradeStatus == "TRADE_CLOSED" { //交易关闭
		switch passbackParams.Get("module") { //取消商城交易
		case "goods_order":
			_, _, err = s.goodsDao.GoodsNumAdd(ctx, uid, notification.OutTradeNo)
			break
		}
	} else if notification.TradeStatus == "TRADE_SUCCESS" { //交易成功
		switch passbackParams.Get("module") {
		case "goods_order": //商城交易
			err = s.goodsNotifyPay(ctx, uid, notification, response)
			break
		}
	}
	if err != nil {
		logs.Error("AlipayCallbackPay Register err=交易失败,res=%v,fErr=%v", response, err)
		return &pb.AlipayCallbackPayResponse{}, msError.GrpcError(biz.RequestDataError)
	}
	//添加回调记录
	ctx = context.TODO()
	err = s.userDao.AddAlipayNotifyLog(ctx, &entity.UserAlipayNotifyLog{
		UID:       uid,
		Extension: passbackParams.Get("module"),
		OrderNo:   notification.OutTradeNo,
		Status:    string(notification.TradeStatus),
		DataJson:  notification,
		AddTime:   time.Now().Format(time.DateTime),
	})
	if err != nil {
		logs.Error("AlipayCallbackPay Register err=添加回调记录失败,res=%v,fErr=%v", response, err)
		return &pb.AlipayCallbackPayResponse{}, msError.GrpcError(biz.SqlError)
	}
	return &pb.AlipayCallbackPayResponse{}, nil
}

func (s *AlipayService) goodsNotifyPay(ctx context.Context, uid uint, notification *alipay.Notification, response string) error {
	order := s.goodsDao.MongoGetOrderByOrderNo(ctx, uid, notification.OutTradeNo)
	if order == nil || order.UID == 0 {
		return fmt.Errorf("goodsNotifyPay 获取数据错误")
	}
	return s.goodsDao.OrderPay(ctx, order, response)
}

func NewAlipayService(manager *repo.Manager) *AlipayService {
	return &AlipayService{
		userDao:  dao.NewUserDao(manager),
		goodsDao: dao.NewGoodsDao(manager),
	}
}
